home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / nihcl-30.lha / nihcl-3.0 / vector / Vec.m4 < prev    next >
Text File  |  1990-05-16  |  20KB  |  884 lines

  1. /* Vec.m4 -- M4 code templates for NIHCL Vector classes
  2.  
  3.     THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
  4.     "UNITED STATES GOVERNMENT WORK".  IT WAS WRITTEN AS A PART OF THE
  5.     AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE.  THIS MEANS IT
  6.     CANNOT BE COPYRIGHTED.  THIS SOFTWARE IS FREELY AVAILABLE TO THE
  7.     PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
  8.     RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
  9.  
  10. Author:
  11.     K. E. Gorlen
  12.     Bg. 12A, Rm. 2033
  13.     Computer Systems Laboratory
  14.     Division of Computer Research and Technology
  15.     National Institutes of Health
  16.     Bethesda, Maryland 20892
  17.     Phone: (301) 496-1111
  18.     uucp: uunet!nih-csl!kgorlen
  19.     Internet: kgorlen@alw.nih.gov
  20.     May, 1986
  21.  
  22. Function:
  23.     
  24. This file contains M4 macro definitions for almost all of the functions
  25. needed to implement the NIHCL vector classes.
  26.  
  27. Modification History:
  28.  
  29. $Log:    Vec.m4,v $
  30. Revision 3.0  90/05/16  23:00:41  kgorlen
  31. Release for 1st edition.
  32.  
  33. */
  34. // WARNING: Modify the M4 macros, not the C++ code they generate!
  35. // WARNING: Assumes 8 bits per character.
  36.  
  37. define(CONCAT,$1$2$3$4$5$6$7$8$9)
  38.  
  39. define(CAP,`CONCAT(translit(substr($1,0,1),abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ),substr($1,1))')
  40.  
  41. define(PROLOGUE,
  42.  
  43. ``#include'' "$1Vec.h"
  44. ``#include'' "nihclIO.h"
  45.  
  46. ``#define'' THIS $1Vec
  47. ``#define'' BASE Vector
  48. ``#define'' BASE_CLASSES Vector::desc()
  49. ``#define'' MEMBER_CLASSES
  50. ``#define'' VIRTUAL_BASE_CLASSES
  51.  
  52. DEFINE_CLASS($1Vec,1,"$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/vector/RCS/Vec.m4,v 3.0 90/05/16 23:00:41 kgorlen Rel $",NULL,NULL);
  53.  
  54. typedef float Float;
  55. typedef double Double;
  56. typedef unsigned char Byte;
  57. typedef short Short;
  58. typedef int Int;
  59. typedef long Long;
  60.  
  61. void $1Copy(const $1* src, $1* dst, unsigned long count)
  62. // Copy n $1 elements from src to dst.
  63. {
  64.     const $1* sp = src;
  65.     $1* dp = dst;
  66. ``#ifndef'' DUFF
  67.     unsigned long n = count;
  68.     while (n--) *dp++ = *sp++;
  69. ``#else''
  70. //  Unrolled loop using Duff's Device:
  71.     unsigned long n = (count+7)>>3;
  72.     switch (count & 7) {
  73.         case 0:    do {    *dp++ = *sp++;
  74.         case 7:        *dp++ = *sp++;
  75.         case 6:        *dp++ = *sp++;
  76.         case 5:        *dp++ = *sp++;
  77.         case 4:        *dp++ = *sp++;
  78.         case 3:        *dp++ = *sp++;
  79.         case 2:        *dp++ = *sp++;
  80.         case 1:        *dp++ = *sp++;
  81.         } while (--n > 0);
  82.     }
  83. ``#endif''
  84. }
  85.  
  86. void Temp$1Vec::free()        { delete this; }
  87.  
  88. bool $1Vec::isEqual(const Object& u) const
  89. // Test $1Vecs equal.
  90. {
  91.     const $1Vec* U = castdown(&u);
  92.     if (!u.isSpecies(classDesc) || n!=U->n) return NO;
  93.     unsigned i = n;
  94.     $1* vp = v;
  95.     $1* up = U->v;
  96.     while (i--) if (*vp++ != *up++) return NO;
  97.     return YES;
  98. }
  99.                                     
  100. const Class* $1Vec::species() const    { return &classDesc; }
  101.  
  102. void $1Vec::deepenShallowCopy() {}
  103.  
  104. $1Vec::$1Vec(OIOin& strm) : BASE(strm)
  105. {
  106.     v = new $1[n];
  107.     strm.get(v,n);
  108. }
  109.  
  110. void $1Vec::storer(OIOout& strm) const
  111. {
  112.     Vector::storer(strm);
  113.     strm.put(v,n);
  114. }
  115.  
  116. $1Vec::$1Vec(OIOifd& fd) : BASE(fd)
  117. {
  118.     v = new $1[n];
  119.     fd.get(v,n);
  120. }
  121.  
  122. void $1Vec::storer(OIOofd& fd) const
  123. {
  124.     Vector::storer(fd);
  125.     fd.put(v,n);
  126. }
  127.  
  128. extern const int NIHCL_INDEXRANGE;
  129. extern const int NIHCL_SLICERANGE;
  130. extern const int NIHCL_VECTORLENGTH;
  131. extern const int NIHCL_VECTORSELECT;
  132.  
  133. void $1Vec::indexRangeErr() const
  134. {
  135.     setError(NIHCL_INDEXRANGE,DEFAULT,this,className());
  136. }
  137.  
  138. void $1Vec::selectErr(const BitVec& V) const
  139. {
  140.     setError(NIHCL_VECTORSELECT,DEFAULT,this,"$1Vec",length(),sum(V),&V,V.length());
  141. }
  142.  
  143. void $1Slice::selectErr(const BitVec& V) const
  144. {
  145.     NIHCL::setError(NIHCL_VECTORSELECT,DEFAULT,this,"$1Slice",length(),sum(V),&V,V.length());
  146. }
  147.  
  148. )
  149.  
  150. define(TYPE1_lengthErr_TYPE2,
  151. void $1::lengthErr(const $2& V) const
  152. {
  153.     NIHCL::setError(NIHCL_VECTORLENGTH,DEFAULT,this,"$1",length(),&V,"$2",V.length());
  154. }
  155. )
  156.  
  157. define(TYPEVec_CTOR_I,
  158. $1Vec::$1Vec(unsigned lngth) : BASE(lngth)
  159. // Construct an uninitialized $1Vec of the length specified.
  160. {
  161.     v = NULL;
  162.     if (lngth != 0) v = new $1[lngth];
  163. }
  164. )
  165.  
  166. define(TYPEVec_CTOR_I_TYPE_TYPE,
  167. $1Vec::$1Vec(unsigned lngth, $1 from, $1 by) : BASE(lngth)
  168. // Construct a $1Vec of the length specified and initialize it to
  169. // (v[0] = from, v[i] = v[i-1]+by for i = 1...n-1)
  170. {
  171.     v = NULL;
  172.     if (lngth != 0) {
  173.         v = new $1[lngth];
  174.         $1* vp =v;
  175.         for ($1 x =from; lngth-- >0; x += by) *vp++ = x;
  176.     }
  177. }
  178. )
  179.  
  180. define(TYPEVec_CTOR_TYPEPTR_I,
  181. $1Vec::$1Vec(const $1* src, unsigned lngth) : BASE(lngth)
  182. // Construct a $1Vec and initialize it from the specified $1 vector.
  183. {
  184.     v = NULL;
  185.     if (lngth != 0) {
  186.         v = new $1[lngth];
  187.         $1Copy(src,v,lngth);
  188.     }
  189. }
  190. )
  191.  
  192. define(TYPEVec_CTOR_TYPEVec,
  193. $1Vec::$1Vec(const $1Vec& U) : BASE(U.n)
  194. // Construct a $1Vec and initialize it from the specified $1Vec U.
  195. {
  196.     v = NULL;
  197.     if (n != 0) {
  198.         v = new $1[n];
  199.         $1Copy(U.v,v,n);
  200.     }
  201. }
  202. )
  203.  
  204. define(TYPEVec_CTOR_TYPESlice,
  205. $1Vec::$1Vec(const $1Slice& s) : BASE(s.length())
  206. // Construct a $1Vec from a slice of another $1Vec.
  207. {
  208.     v = NULL;
  209.     if (n != 0) {
  210.         v = new $1[n];
  211.         const $1* sp = s.pt();
  212.         $1* dp = v;
  213.         int i = s.length();
  214.         int j = s.stride();
  215.         while (i--) { *dp++ = *sp; sp += j; }
  216.     }
  217. }
  218. )
  219.  
  220. define(TYPESlice_CTOR_TYPEVec_I_I_I,
  221. $1Slice::$1Slice(const $1Vec& v, int pos, unsigned lgt, int stride)
  222. // Construct a $1Slice from a $1Vec.
  223. {
  224.     if ((unsigned)(pos + (lgt-1)*stride) >= v.length())
  225.         NIHCL::setError(NIHCL_SLICERANGE,DEFAULT,&v,v.className(),v.length(),pos,lgt,stride);
  226.     V = &($1Vec&)v;  p = &(($1Vec&)v)[pos];  l = lgt;  k = stride;
  227. }
  228. )
  229.  
  230. define(TYPESlice_CTOR_TYPEPick,
  231. $1Slice::$1Slice(const $1Pick& s)
  232. // Construct a $1Vec slice from IntVec-subscripted elements of $1Vec.
  233. // Can't do this with $1Slct::operator $1Slice() because of Temp$1Vec
  234. {
  235.     $1Vec& T = *new Temp$1Vec();
  236.     T = (*s.V)[*s.X];
  237.     V = &T;  p = T.pt();  l = T.length();  k = 1;
  238. }
  239. )
  240.  
  241. define(TYPESlice_CTOR_TYPESlice,
  242. $1Slice::$1Slice(const $1Slice& s)
  243. // Private $1Slice copy constructor
  244. {
  245.     V = s.V;
  246.     p = s.p;
  247.     l = s.l;
  248.     k = s.k;
  249. }
  250. )
  251.  
  252. define(TYPESlice_CTOR_TYPESlct,
  253. $1Slice::$1Slice(const $1Slct& s)
  254. // Construct a $1Vec slice from $1Vec-selected elements of $1Vec.
  255. // Can't do this with $1Slct::operator $1Slice() because of Temp$1Vec
  256. {
  257.     $1Vec& T = *new Temp$1Vec();
  258.     T = (*s.V)[*s.B];
  259.     V = &T;  p = T.pt();  l = T.length();  k = 1;
  260. }
  261. )
  262.  
  263. define(TYPEVec_ASN_TYPEVec,
  264. void $1Vec::operator=(const $1Vec& U)
  265. // Assign the argument $1Vec U to this $1Vec.
  266. {
  267.     if (v != U.v) {
  268.         delete v;
  269.         v = NULL;
  270.         if ((n = U.n) != 0) {
  271.             v = new $1[n];
  272.             $1Copy(U.v,v,n);
  273.         }
  274.     }
  275. }
  276. )
  277.  
  278. define(TYPEVec_ASN_TYPESlice,
  279. void $1Vec::operator=(const $1Slice& s)
  280. // Assign a slice of a $1Vec to this $1Vec.
  281. {
  282.     int i = s.length();        // slice length
  283.     if ((n = i) == 0) {        // empty slice
  284.         delete v;
  285.         v = NULL;
  286.         return;
  287.     }
  288.     const $1* sp = s.pt();
  289.     int j = s.stride();
  290.     if (this == s.V) {    // V = V(i,j,k)
  291.         $1* t = v;
  292.         $1* dp = new $1[i];
  293.         v = dp;
  294.         while (i--) { *dp++ = *sp; sp += j; }
  295.         delete t;
  296.     }
  297.     else {
  298.         delete v;
  299.         $1* dp = new $1[i];
  300.         v = dp;
  301.         while (i--) { *dp++ = *sp; sp += j; }
  302.     }
  303. }
  304. )
  305.  
  306. define(TYPEVec_ASN_TYPESlct,
  307. void $1Vec::operator=(const $1Slct& s)
  308. // Assign the BitVec-selected elements of a $1Vec to this $1Vec.
  309. {
  310.     if ((n = sum(*s.B)) == 0) {    // return zero length result
  311.         delete v;
  312.         v = NULL;
  313.         return;
  314.     }
  315.     $1* sp = s.V->pt();
  316.     $1* t = v;
  317.     if (this != s.V) delete t;    // not V = V[BitVec&]
  318.     $1* dp = new $1[n];
  319.     v = dp;
  320.     BITVECSCAN(*s.B, s.length(), *dp++ = *sp;  sp++)
  321.     if (this == s.V) delete t;    // case V = V[BitVec&]
  322. }
  323. )
  324.  
  325. define(TYPEVec_ASN_TYPEPick,
  326. void $1Vec::operator=(const $1Pick& s)
  327. // Assign the IntVec-subscripted elements of a $1Vec to this $1Vec.
  328. {
  329.     unsigned i = s.length();
  330.     unsigned l;
  331.     if ((l = i) == 0) {    // return zero length result
  332.         delete v;
  333.         v = NULL;  n = 0;
  334.         return;
  335.     }
  336.     $1* t = v;
  337.     if (this != s.V) delete t;    // not V = V[IntVec&]
  338.     $1* dp = new $1[l];
  339.     $1* u = dp;
  340.     const int* xp = (*s.X).pt();
  341.     $1Vec& S = *s.V;
  342.     while (i--) { *dp++ = S[*xp++]; }
  343.     v = u;  n = l;
  344.     if (this == s.V) delete t;    // case V = V[IntVec&]
  345. }
  346. )
  347.  
  348. define(TYPEVec_ASN_TYPE,
  349. void $1Vec::operator=($1 scalar)
  350. // Assign a scalar to all elements of this $1Vec.
  351. {
  352.     unsigned i = n;
  353.     $1* dp = v;
  354.     $1 c = scalar;
  355.     while (i--) *dp++ = c;
  356. }
  357. )
  358.  
  359. define(TYPESlice_ASN_TYPEVec,
  360. void $1Slice::operator=(const $1Vec& U)
  361. // Assign a $1Vec to this $1Vec slice.
  362. {
  363.     int i = l;
  364.     if (i != U.length()) lengthErr(U);
  365.     $1* dp = p;
  366.     const $1* sp = U.pt();
  367.     int j = k;
  368.     while (i--) { *dp = *sp++; dp += j; }
  369. }
  370. )
  371.  
  372. define(TYPESlice_ASN_TYPESlice,
  373. void $1Slice::operator=(const $1Slice& s)
  374. // Assign a $1Vec slice to this $1Vec slice.
  375. {
  376.     int i = l;
  377.     if (i != s.l) lengthErr(s);
  378.     $1* dp = p;
  379.     $1* sp = s.p;
  380.     int dj = k;
  381.     int sj = s.k;
  382.     while (i--) { *dp = *sp; dp += dj; sp += sj; }
  383. }
  384. )
  385.  
  386. define(TYPESlice_ASN_TYPEPick,
  387. void $1Slice::operator=(const $1Pick& s)
  388. // Assign the IntVec-subscripted elements of a $1Vec to this $1Vec slice.
  389. {
  390.     int i = l;
  391.     if (i != s.length()) lengthErr(*s.X);
  392.     $1* dp = p;
  393.     const int* xp = (*s.X).pt();
  394.     int j = k;
  395.     $1Vec& S = *s.V;
  396.     while (i--) { *dp = S[*xp++]; dp += j; }
  397. }
  398. )
  399.  
  400. define(TYPESlice_ASN_TYPESlct,
  401. void $1Slice::operator=(const $1Slct& s)
  402. // Assign the BitVec-selected elements of a $1Vec to this $1Vec slice.
  403. {
  404.     if (l != sum(*s.B)) lengthErr(s);
  405.     $1* sp = s.V->pt();
  406.     $1* dp = p;
  407.     int j = k;
  408.     BITVECSCAN(*s.B, s.length(), { *dp = *sp;  dp += j; };  sp++)
  409. }
  410. )
  411.  
  412. define(TYPESlice_ASN_TYPE,
  413. void $1Slice::operator=($1 scalar)
  414. // Assign a scalar to all elements of this $1Vec slice.
  415. {
  416.     int i = l;
  417.     int j = k;
  418.     $1* dp = p;
  419.     $1 c = scalar;
  420.     while (i--) { *dp = c; dp += j; }
  421. }
  422. )
  423.  
  424. define(FRIEND_OP_TYPESlice__TYPEVec,
  425. $1Vec operator$2(const $1Slice& s)
  426. // Unary operator on $1Vec slice.
  427. {
  428.     int i = s.length();
  429.     $1Vec T(i);
  430.     const $1* sp = s.pt();
  431.     $1* dp = T.pt();
  432.     int j = s.stride();
  433.     while (i--) { *dp++ = $2(*sp);  sp += j; }
  434.     return T;
  435. }
  436. )
  437.  
  438. define(FRIEND_INCDECOP_TYPESlice__TYPEVec,
  439. $1Vec operator$2($1Slice& s)
  440. // Unary inc/dec operator on $1Vec slice.
  441. {
  442.     int i = s.length();
  443.     $1Vec T(i);
  444.     $1* sp = s.pt();
  445.     $1* dp = T.pt();
  446.     int j = s.stride();
  447.     while (i--) { *dp++ = $2(*sp);  sp += j; }
  448.     return T;
  449. }
  450. )
  451.  
  452. define(FRIEND_TYPESlice_OP_TYPESlice__TYPEVec,
  453. $1Vec operator$2(const $1Slice& u, const $1Slice& v)
  454. // Binary arithmetic operator on two $1Vec slices
  455. {
  456.     int i = u.length();
  457.     if (i != v.length()) u.lengthErr(v);
  458.     $1Vec T(i);
  459.     const $1* up = u.pt();
  460.     const $1* vp = v.pt();
  461.     $1* dp = T.pt();
  462.     int uj = u.stride();
  463.     int vj = v.stride();
  464.     while (i--) { *dp++ = *up $2 *vp;  up += uj; vp += vj; }
  465.     return T;
  466. }
  467. )
  468.  
  469. define(FRIEND_TYPESlice_OP_TYPE__TYPEVec,
  470. $1Vec operator$2(const $1Slice& s, $1 scalar)
  471. // Binary arithmetic operator on $1Vec slice and scalar.
  472. {
  473.     int i = s.length();
  474.     $1Vec T(i);
  475.     const $1* sp = s.pt();
  476.     $1* dp = T.pt();
  477.     int j = s.stride();
  478.     $1 c = scalar;
  479.     while (i--) { *dp++ = *sp $2 c; sp += j; }
  480.     return T;
  481. }
  482. )
  483.  
  484. define(FRIEND_TYPE_OP_TYPESlice__TYPEVec,
  485. $1Vec operator$2($1 scalar, const $1Slice& s)
  486. // Binary arithmetic operator on scalar and $1Vec slice.
  487. {
  488.     int i = s.length();
  489.     $1Vec T(i);
  490.     const $1* sp = s.pt();
  491.     $1* dp = T.pt();
  492.     int j = s.stride();
  493.     $1 c = scalar;
  494.     while (i--) { *dp++ = c $2 *sp; sp += j; }
  495.     return T;
  496. }
  497. )
  498.  
  499. define(FRIEND_TYPESlice_OP_TYPESlice__BitVec,
  500. BitVec operator$2(const $1Slice& u, const $1Slice& v)
  501. // Relational operator on two $1Vec slices.
  502. {
  503.     if (u.length() != v.length()) u.lengthErr(v);
  504.     BitVec B(u.length());
  505.     const $1* up = u.pt();
  506.     const $1* vp = v.pt();
  507.     int uj = u.stride();
  508.     int vj = v.stride();
  509.     BITVECGEN(B.pt(), u.length(), *up $2 *vp, up += uj; vp += vj)
  510.     return B;
  511. }
  512. )
  513.  
  514. define(FRIEND_TYPESlice_OP_TYPE__BitVec,
  515. BitVec operator$2(const $1Slice& s, $1 scalar)
  516. // Relational operator on $1Vec slice and scalar.
  517. {
  518.     BitVec B(s.length());
  519.     const $1* vp = s.pt();
  520.     int vj = s.stride();
  521.     $1 c = scalar;
  522.     BITVECGEN(B.pt(), s.length(), *vp $2 c, vp += vj)
  523.     return B;
  524. }
  525. )
  526.  
  527. define(FRIEND_TYPE_OP_TYPESlice__BitVec,
  528. BitVec operator$2($1 scalar, const $1Slice& s)
  529. // Relational operator on scalar and $1Vec slice.
  530. {
  531.     BitVec B(s.length());
  532.     const $1* vp = s.pt();
  533.     int vj = s.stride();
  534.     $1 c = scalar;
  535.     BITVECGEN(B.pt(), s.length(), c $2 *vp, vp += vj)
  536.     return B;
  537. }
  538. )
  539.  
  540. define(FRIEND_TYPESlice_ASNOP_TYPESlice,
  541. void operator$2($1Slice& u, const $1Slice& v)
  542. // Assignment arithmetic operator on two $1Vec slices.
  543. {
  544.     int i = u.length();
  545.     if (i != v.length()) u.lengthErr(v);
  546.     $1* up = u.pt();
  547.     const $1* vp = v.pt();
  548.     int uj = u.stride();
  549.     int vj = v.stride();
  550.     while (i--) { *up $2 *vp;  up += uj; vp += vj; }
  551. }
  552. )
  553.  
  554. define(FRIEND_TYPESlice_ASNOP_TYPE,
  555. void operator$2($1Slice& s, $1 scalar)
  556. // Assignment arithmetic operator on scalar and $1Vec slice.
  557. {
  558.     int i = s.length();
  559.     $1* dp = s.pt();
  560.     int j = s.stride();
  561.     $1 c = scalar;
  562.     while (i--) { *dp $2 c; dp += j; }
  563. }
  564. )
  565.  
  566. define(TYPEPick_ASN_TYPEVec,
  567. void $1Pick::operator=(const $1Vec& U)
  568. // Assign $1Vec to IntVec-subscripted elements of $1Vec.
  569. {
  570.     int i = length();
  571.     if (i != U.length()) lengthErr(*X,U);
  572.     const int* xp = (*X).pt();
  573.     const $1* up = U.pt();
  574.     $1Vec& D = *V;
  575.     while (i--) { D[*xp++] = *up++; }
  576. }
  577. )
  578.  
  579. define(TYPEPick_ASN_TYPEPick,
  580. void $1Pick::operator=(const $1Pick& s)
  581. // Assign IntVec-subscripted elements of $1Vec to IntVec-subscripted elements of $1Vec.
  582. {
  583.     int i = length();
  584.     if (i != s.length()) lengthErr(*X,*s.X);
  585.     const int* xp = (*X).pt();
  586.     const int* yp = (*s.X).pt();
  587.     $1Vec& D = *V;
  588.     $1Vec& S = *s.V;
  589.     while (i--) { D[*xp++] = S[*yp++]; }
  590. }
  591. )
  592.  
  593. define(TYPEPick_ASN_TYPESlct,
  594. void $1Pick::operator=(const $1Slct& s)
  595. // Assign BitVec-selected elements of $1Vec to IntVec-subscripted elements of $1Vec.
  596. {
  597.     if (length() != sum(*s.B)) X->selectErr(*s.B);
  598.     const int* xp = (*X).pt();
  599.     const $1* sp = (*s.V).pt();
  600.     $1Vec& D = *V;
  601.     BITVECSCAN(*s.B, length(), D[*xp++] = *sp;  sp++)
  602. }
  603. )
  604.  
  605. define(TYPEPick_ASN_TYPESlice,
  606. void $1Pick::operator=(const $1Slice& s)
  607. // Assign $1Vec slice to IntVec-subscripted elements of $1Vec.
  608. {
  609.     int i = length();
  610.     if (i != s.length()) s.lengthErr(*X);
  611.     const int* xp = (*X).pt();
  612.     const $1* sp = s.pt();
  613.     int j = s.stride();
  614.     $1Vec& D = *V;
  615.     while (i--) { D[*xp++] = *sp;  sp += j; }
  616. }
  617. )
  618.  
  619. define(TYPEPick_ASN_TYPE,
  620. void $1Pick::operator=($1 scalar)
  621. // Assign scalar to all IntVec-subscripted elements of $1Vec.
  622. {
  623.     int i = length();
  624.     const int* xp = (*X).pt();
  625.     $1 c = scalar;
  626.     $1Vec& D = *V;
  627.     while (i--) { D[*xp++] = c; }
  628. }
  629. )
  630.  
  631. define(TYPESlct_ASN_TYPEVec,
  632. void $1Slct::operator=(const $1Vec& U)
  633. // Assign a $1Vec to BitVec-selected elements of $1Vec.
  634. {
  635.     if (U.length() != sum(*B)) U.selectErr(*B);
  636.     $1* dp = V->pt();
  637.     const $1* sp = U.pt();
  638.     BITVECSCAN(*B, U.length(), *dp = *sp++;  dp++)
  639. }
  640. )
  641.  
  642. define(TYPESlct_ASN_TYPEPick,
  643. void $1Slct::operator=(const $1Pick& s)
  644. // Assign IntVec-subscripted elements of $1Vec to BitVec-selected elements of $1Vec.
  645. {
  646.     if (s.length() != sum(*B)) s.X->selectErr(*B);
  647.     $1* dp = V->pt();
  648.     const int* xp = (*s.X).pt();
  649.     $1Vec& W = *s.V;
  650.     BITVECSCAN(*B, length(), *dp = W[*xp++];  dp++)
  651. }
  652. )
  653.  
  654. define(TYPESlct_ASN_TYPESlct,
  655. void $1Slct::operator=(const $1Slct& s)
  656. // Assign BitVec-selected elements of $1Vec to BitVec-selected elements of $1Vec.
  657. {
  658.     $1Vec T;
  659.     T = (*s.V)[*s.B];
  660.     (*V)[*B] = T;
  661. }
  662. )
  663.  
  664. define(TYPESlct_ASN_TYPESlice,
  665. void $1Slct::operator=(const $1Slice& s)
  666. // Assign $1Vec slice to BitVec-selected elements of $1Vec.
  667. {
  668.     if (s.length() != sum(*B)) s.selectErr(*B);
  669.     $1* dp = V->pt();
  670.     const $1* sp = s.pt();
  671.     int j = s.stride();
  672.     BITVECSCAN(*B, length(), { *dp = *sp;  sp += j; };  dp++)
  673. }
  674. )
  675.  
  676. define(TYPESlct_ASN_TYPE,
  677. void $1Slct::operator=($1 scalar)
  678. // Assign scalar to all BitVec-selected elements of $1Vec.
  679. {
  680.     $1* dp = V->pt();
  681.     $1 c = scalar;
  682.     BITVECSCAN(*B, length(), *dp = c;  dp++)
  683. }
  684. )
  685.  
  686. define(TYPESlice_APPLY_FUN__TYPEVec,
  687. $1Vec $1Slice::apply(mathFunTy f) const
  688. // Apply function to each element of vector slice
  689. {
  690.     int i = l;
  691.     $1Vec T(i);
  692.     $1* sp = p;
  693.     $1* dp = T.pt();
  694.     int j = k;
  695.     while (i--) { *dp++ = f(*sp);  sp += j; }
  696.     return T;
  697. }
  698. )
  699.  
  700. define(FRIEND_abs_TYPESlice,
  701. $1Vec abs(const $1Slice& s)
  702. // Absolute value of $1Vec slice.
  703. {
  704.     int i = s.length();
  705.     $1Vec T(i);
  706.     const $1* sp = s.pt();
  707.     $1* dp = T.pt();
  708.     int j = s.stride();
  709.     while (i--) { *dp++ = ABS(*sp);  sp += j; }
  710.     return T;
  711. }
  712. )
  713.  
  714. define(FRIEND_atan2_TYPESlice_TYPESlice,
  715. $1Vec atan2(const $1Slice& u,const $1Slice& v)
  716. // Arctangent of u/v.
  717. {
  718.     int i = u.length();
  719.     if (i != v.length()) u.lengthErr(v);
  720.     $1Vec T(i);
  721.     const $1* up = u.pt();
  722.     const $1* vp = v.pt();
  723.     $1* dp = T.pt();
  724.     int uj = u.stride();
  725.     int vj = v.stride();
  726.     while (i--) { *dp++ = $2(*up,*vp);  up += uj;  vp += vj; }
  727.     return T;
  728. }
  729. )
  730.  
  731. define(FRIEND_pow_TYPESlice_TYPESlice,
  732. $1Vec pow(const $1Slice& u,const $1Slice& v)
  733. // u to the v power.
  734. {
  735.     int i = u.length();
  736.     if (i != v.length()) u.lengthErr(v);
  737.     $1Vec T(i);
  738.     const $1* up = u.pt();
  739.     const $1* vp = v.pt();
  740.     $1* dp = T.pt();
  741.     int uj = u.stride();
  742.     int vj = v.stride();
  743.     while (i--) { *dp++ = $2(*up,*vp);  up += uj;  vp += vj; }
  744.     return T;
  745. }
  746. )
  747.  
  748. define(FRIEND_cumsum_TYPESlice,
  749. $1Vec cumsum(const $1Slice& s)
  750. // Cumulative sum of $1Vec slice.
  751. // Note: V == delta(cumsum(V)) == cumsum(delta(V))
  752. {
  753.     unsigned i = s.length();
  754.     $1Vec T(i);
  755.     const $1* sp = s.pt();
  756.     $1* dp = T.pt();
  757.     $1 c = 0;
  758.     int j = s.stride();
  759.     while (i--) { *dp++ = c += *sp;  sp += j; }
  760.     return T;
  761. }
  762. )
  763.  
  764. define(FRIEND_delta_TYPESlice,
  765. $1Vec delta(const $1Slice& s)
  766. // Element differences of $1Vec slice.
  767. // Note: V == delta(cumsum(V)) == cumsum(delta(V))
  768. {
  769.     unsigned i = s.length();
  770.     $1Vec T(i);
  771.     const $1* sp = s.pt();
  772.     $1* dp = T.pt();
  773.     $1 c = 0;
  774.     int j = s.stride();
  775.     while (i--) { *dp++ = *sp - c;  c = *sp;  sp += j; }
  776.     return T;
  777. }
  778. )
  779.  
  780. define(FRIEND_dot_TYPESlice_TYPESlice,
  781. $1 dot(const $1Slice& u,const $1Slice& v)
  782. // Vector dot product.
  783. {
  784.     int i = u.length();
  785.     if (i != v.length()) u.lengthErr(v);
  786.     $1 t =0;
  787.     const $1* up = u.pt();
  788.     const $1* vp = v.pt();
  789.     int uj = u.stride();
  790.     int vj = v.stride();
  791.     while (i--) { t += *up * *vp;  up += uj;  vp += vj; }
  792.     return t;
  793. }
  794. )
  795.  
  796. define(FRIEND_max_TYPESlice,
  797. int max(const $1Slice& s)
  798. // Index of maximum element.
  799. {
  800.     if (s.length() == 0) s.V->emptyErr("max");
  801.     const $1* sp = s.pt();
  802.     $1 t = *sp;
  803.     int j = s.stride();
  804.     int x = 0;
  805.     for (int i =0; i<s.length(); i++) {
  806.         if (*sp > t) { t = *sp;  x = i; }
  807.         sp += j;
  808.     }
  809.     return x;
  810. }
  811. )
  812.  
  813. define(FRIEND_min_TYPESlice,
  814. int min(const $1Slice& s)
  815. // Index of minimum element.
  816. {
  817.     if (s.length() == 0) s.V->emptyErr("min");
  818.     const $1* sp = s.pt();
  819.     $1 t = *sp;
  820.     int j = s.stride();
  821.     int x = 0;
  822.     for (int i =0; i<s.length(); i++) {
  823.         if (*sp < t) { t = *sp;  x = i; }
  824.         sp += j;
  825.     }
  826.     return x;
  827. }
  828. )
  829.  
  830. define(FRIEND_prod_TYPESlice,
  831. $1 prod(const $1Slice& s)
  832. // Product of $1Vec slice elements.
  833. {
  834.     int i = s.length();
  835.     const $1* sp = s.pt();
  836.     $1 t = 1;
  837.     int j = s.stride();
  838.     while (i--) { t *= *sp;  sp += j; }
  839.     return t;
  840. }
  841. )
  842.  
  843. define(FRIEND_reverse_TYPESlice,
  844. $1Vec reverse(const $1Slice& s)
  845. // Reverse vector elements.
  846. {
  847.     int i = s.length();
  848.     $1Vec T(i);
  849.     const $1* sp = s.pt();
  850.     $1* dp = &T(i);
  851.     int j = s.stride();
  852.     while (i--) { *(--dp) = *sp;  sp += j; }
  853.     return T;
  854. }
  855. )
  856.  
  857. define(FRIEND_sum_TYPESlice,
  858. $1 sum(const $1Slice& s)
  859. // Sum of vector elements.
  860. {
  861.     int i = s.length();
  862.     const $1* sp = s.pt();
  863.     $1 t = 0;
  864.     int j = s.stride();
  865.     while (i--) { t += *sp;  sp += j; }
  866.     return t;
  867. }
  868. )
  869.  
  870. define(FRIEND_acos_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  871. define(FRIEND_asin_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  872. define(FRIEND_atan_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  873. define(FRIEND_ceil_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  874. define(FRIEND_cos_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  875. define(FRIEND_cosh_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  876. define(FRIEND_exp_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  877. define(FRIEND_floor_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  878. define(FRIEND_log_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  879. define(FRIEND_sin_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  880. define(FRIEND_sinh_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  881. define(FRIEND_sqrt_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  882. define(FRIEND_tan_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  883. define(FRIEND_tanh_TYPESlice,$1Vec $2(const $1Slice& V) { return V.apply($2); })
  884.